home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / FREENET / BRODIE / CAPTURET.C < prev    next >
C/C++ Source or Header  |  1995-06-05  |  4KB  |  176 lines

  1. /* captureTCP.c */
  2.  
  3. /* (C) Copyright 1995, Stewart Brodie */
  4.  
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <stdarg.h>
  10. #include <errno.h>
  11. #include <ctype.h>
  12.  
  13. #include "sys/errno.h"
  14. #include "netdb.h"
  15. #include "netinet/in.h"
  16. #include "sys/socket.h"
  17. #include "sys/ioctl.h"
  18. #include "sys/byteorder.h"
  19. #include "sys/select.h"
  20.  
  21. static int s = -1,t = -1;
  22.  
  23. static void do_stop(void)
  24. {
  25.         if (s > -1) { shutdown(s, 2); close(s); }
  26.         if (t > -1) { shutdown(t, 2); close(t); }
  27. }
  28.  
  29. #define SYNTAX "captureTCP [-repeat] [<port|name> [capture file]]"
  30.  
  31. int main(int argc, char *argv[])
  32. {
  33.         struct sockaddr_in    sin;
  34.         struct hostent *he;
  35.         int port = 0, repeat = 0,size;
  36.         FILE *cap = NULL;
  37.     char cpbuf[BUFSIZ];
  38.     fd_set f;
  39.  
  40.  
  41.         fprintf(stderr, "captureTCP (C) Stewart Brodie (" __DATE__ ") vsn 0.01\n");
  42.         while (argc > 1) {
  43.         if (strcmp(argv[1], "-repeat")==0) repeat = 1;
  44.         else if (isdigit(*(argv[1]))) port = atoi(argv[1]);
  45.         else if (*(argv[1]) == '-') {
  46.             fprintf(stderr, "Syntax: " SYNTAX "\n");
  47.                 return 1;
  48.         }
  49.         else {
  50.                 if (port == 0) {
  51.                         struct servent *se = getservbyname(argv[1],"tcp");
  52.  
  53.                 if (!se) {
  54.                         fprintf(stderr, "service '%s' not known\n",
  55.                                 argv[1]);
  56.                     return 1;
  57.                 }
  58.                 port = htons(se->s_port);
  59.                 }
  60.                 else if (!cap) {
  61.                         cap = fopen(argv[1], "wb");
  62.                 }
  63.         }
  64.         ++argv; --argc;
  65.         }
  66.  
  67.     if (!cap) cap = stdout;
  68.  
  69.     s = socket(AF_INET, SOCK_STREAM, 0);
  70.     if (s == -1) {
  71.         fprintf(stderr, "socket: %s\n", socket_errno_to_string());
  72.         return 1;
  73.     }
  74.  
  75.     atexit(do_stop);
  76.  
  77.     sin.sin_family = AF_INET;
  78.     sin.sin_port = htons(port);
  79.     sin.sin_addr.s_addr = INADDR_ANY;
  80.     memset(sin.sin_zero, 0, 8);
  81.  
  82.     if (bind(s, &sin, sizeof(sin)) == -1) {
  83.         fprintf(stderr, "bind: %s\n", socket_errno_to_string());
  84.         return 1;
  85.     }
  86.  
  87.     if (listen(s, 5) == -1) {
  88.         fprintf(stderr, "listen: %s\n", socket_errno_to_string());
  89.         return 1;
  90.     }
  91.  
  92.     size = 16;
  93.     if (getsockname(s, &sin, &size) == -1) {
  94.         fprintf(stderr, "bind: %s\n", socket_errno_to_string());
  95.         return 1;
  96.     }
  97.  
  98.     port = htons(sin.sin_port);
  99.         fprintf(stderr, "Bound to port %d (%d,%d for FTP PORT)\n",
  100.             port, port / 256, port % 256);
  101.  
  102.         fprintf(stderr, "Waiting for connection ...\n");
  103.  
  104.         for (;;) {
  105.                 struct timeval timeout;
  106.                 int sr;
  107.                 FD_ZERO(&f);
  108.                 FD_SET(s, &f);
  109.                 timerclear(&timeout);
  110.  
  111.                 sr = select(FD_SETSIZE, &f, NULL, NULL, &timeout);
  112.                 if (sr == -1) {
  113.                         if (errno == EWOULDBLOCK) {
  114.                                 continue;
  115.                         }
  116.                         else {
  117.             fprintf(stderr, "select: %s\n", socket_errno_to_string());
  118.             return 1;
  119.                         }
  120.                 }
  121.                 if (sr == 0) {
  122.                         continue;
  123.                 }
  124.         size = 16;
  125.             t = accept(s, (struct sockaddr *)&sin, &size);
  126.             if (t == -1) {
  127.             fprintf(stderr, "accept: %s\n", socket_errno_to_string());
  128.             return 1;
  129.             }
  130.             break;
  131.     }
  132.  
  133.     he = gethostbyaddr((void *)&sin.sin_addr.s_addr, 4, AF_INET);
  134.     if (!he) {
  135.             fprintf(stderr, "Connection from %s\n", inet_ntoa(sin.sin_addr));
  136.     }
  137.     else {
  138.             fprintf(stderr, "Connection from %s\n", he->h_name);
  139.     }
  140.  
  141.     FD_ZERO(&f);
  142.     FD_SET(t, &f);
  143.  
  144.     for (;;) {
  145.             fd_set f2 = f;
  146.             int in, sr;
  147.             struct timeval timeout;
  148.  
  149.                 timerclear(&timeout);
  150.         sr = select(FD_SETSIZE,&f2,NULL,NULL,&timeout);
  151.         if (sr == -1 && errno == EWOULDBLOCK) continue;
  152.         if (sr == 0) continue;
  153.         if (sr == -1) {
  154.             fprintf(stderr, "select: %s\n", socket_errno_to_string());
  155.             return 1;
  156.         }
  157.  
  158.         in = recv(t, cpbuf, BUFSIZ, 0);
  159.  
  160.             if (in == -1) {
  161.             fprintf(stderr, "recv: %s\n", socket_errno_to_string());
  162.             break;
  163.             }
  164.  
  165.         if (in == 0) break;
  166.  
  167.             if (in > 0) {
  168.                     fwrite(cpbuf, 1, in, cap);
  169.             }
  170.     }
  171.  
  172.     fclose(cap);
  173.     /* rely on atexit function to close sockets */
  174.     return 0;
  175. }
  176.